"""
基本分类：对服装图像进行分类
"""
# TensorFlow and tf.keras
import tensorflow as tf
from tensorflow import keras

# Helper libraries
import numpy as np
import matplotlib.pyplot as plt

print(tf.__version__)

# 导入数据集，分为训练数据集和测试数据集
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

# 设置所有的类别名称
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

#############浏览数据
# 查看数据的类型
print(train_images.shape) # 60000*28*28 表示60000张28*28像素的图片
print(len(train_labels))

#############预处理数据
# 所有图片的像素值（像素值指的是每个像素上的亮度信息）都处于0-255之间
# 将这些值缩小至 0 到 1 之间，然后将其馈送到神经网络模型。为此，请将这些值除以 255。请务必以相同的方式对训练集和测试集进行预处理：
train_images = train_images / 255.0
test_images = test_images / 255.0

#############构建模型

# 设置模型层
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)), # 将图像格式从二维数组（28 x 28 像素）转换成一维数组（28 x 28 = 784 像素） 该层没有要学习的参数，它只会重新格式化数据。
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10) # 返回一个长度为 10 的 logits（对数） 数组 https://www.jianshu.com/p/6c9b0cc6978b
])

# 编译模型
model.compile(optimizer='adam', # 优化器 - 决定模型如何根据其看到的数据和自身的损失函数进行更新。
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), #  用于测量模型在训练期间的准确率。您会希望最小化此函数，以便将模型“引导”到正确的方向上。
              metrics=['accuracy']) # 指标 - 用于监控训练和测试步骤。以下示例使用了准确率，即被正确分类的图像的比率。

############# 训练模型
model.fit(train_images, train_labels, epochs=10)

# 有可能出现过拟合
test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)
print('\nTest accuracy:', test_acc)

# 在模型经过训练后，您可以使用它对一些图像进行预测。模型具有线性输出，即 logits。您可以附加一个 softmax 层，将 logits 转换成更容易理解的概率。
probability_model = tf.keras.Sequential([model,
                                         tf.keras.layers.Softmax()])
